//Small header to get STLport numerous defines:
#include <utility>

#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS)
#  include <rope>

#  if !defined (_STLP_USE_NO_IOSTREAMS)
#    include <sstream>
#  endif
#endif

#include "cppunit/cppunit_proxy.h"

#if defined (_STLP_USE_NAMESPACES)
using namespace std;
#endif

//
// TestCase class
//
class RopeTest : public CPPUNIT_NS::TestCase
{
  CPPUNIT_TEST_SUITE(RopeTest);
#if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS)
  CPPUNIT_IGNORE;
#endif
  CPPUNIT_TEST(io);
#if defined (_STLP_USE_NO_IOSTREAMS)
  CPPUNIT_STOP_IGNORE;
#endif
  CPPUNIT_TEST(find1);
  CPPUNIT_TEST(find2);
  CPPUNIT_TEST(construct_from_char);
  CPPUNIT_TEST(bug_report);
  CPPUNIT_TEST_SUITE_END();

protected:
  void io();
  void find1();
  void find2();
  void construct_from_char();
  void bug_report();
};

CPPUNIT_TEST_SUITE_REGISTRATION(RopeTest);

//
// tests implementation
//
void RopeTest::io()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && !defined (_STLP_USE_NO_IOSTREAMS) 
  char const* cstr = "rope test string";
  crope rstr(cstr);

  {
    ostringstream ostr;
    ostr << rstr;

    CPPUNIT_ASSERT( ostr );
    CPPUNIT_ASSERT( ostr.str() == cstr );
  }
#endif
}

void RopeTest::find1()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 
  crope r("Fuzzy Wuzzy was a bear");
  crope::size_type n = r.find( "hair" );
  CPPUNIT_ASSERT( n == crope::npos );

  n = r.find("ear");

  CPPUNIT_ASSERT( n == (r.size() - 3) );
#endif
}

void RopeTest::find2()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 
  crope r("Fuzzy Wuzzy was a bear");
  crope::size_type n = r.find( 'e' );
  CPPUNIT_ASSERT( n == (r.size() - 3) );
#endif
}

void RopeTest::construct_from_char()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 
  crope r('1');
  char const* s = r.c_str();
  CPPUNIT_ASSERT( '1' == s[0] && '\0' == s[1] );
#endif
}

// Test used for a bug report from Peter Hercek
void RopeTest::bug_report()
{
#if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 
  //first create a rope bigger than crope::_S_copy_max = 23
  // so that any string addition is added to a new leaf
  crope evilRope("12345678901234567890123_");
  //crope* pSevenCharRope( new TRope("1234567") );
  crope sevenCharRope0("12345678");
  crope sevenCharRope1("1234567");
  // add _Rope_RopeRep<c,a>::_S_alloc_granularity-1 = 7 characters
  evilRope += "1234567"; // creates a new leaf
  crope sevenCharRope2("1234567");
  // add one more character to the leaf
  evilRope += '8'; // here is the write beyond the allocated memory
  CPPUNIT_ASSERT( strcmp(sevenCharRope2.c_str(), "1234567") == 0 );
#endif
}
